/***************************************************************************************************
  *Copyright(C),2010-2016,Sumscope
  *FileName	:  pinyin_search.cpp
  *Author	:  scofined.qi
  *Version	:  1.0
  *Date		:  2017/06/04
  *Desc		:  
  *Relation :  
  *Others	:  
  *Function :  
  *History	:  
***************************************************************************************************/
#include "pinyin_search.h"
#include "pinyin.h"
#include "./pinyin/pinyin_search_buffer.h"
#include "../strings/string_page.h"
#include <algorithm>
#include "./pinyin/pinyin_search_engine.h"
#include "./pinyin/pinyin_search_engine2.h"

#ifdef WIN32
#include <process.h>
#endif

#define ROUND_ALIGN(NUM, SIZE) ((NUM%SIZE==0)?NUM:((NUM/SIZE+1)*SIZE))

namespace qb{
	namespace base{
		namespace{
			bool gs_use_refactor = true;
			ISpellSearch* GetSearchEngine()
			{
				if (gs_use_refactor)
					return internal::SpellSearchImpl::instance();
				return internal::SpellSearchMerged::instance();
			}
		}
		typedef internal::BondChangeBuffer BondChangeBuffer;
		/////////////////////////////////////////////////////////////////////////////
		SpellSearch::Collector::Collector(bool build) :m_buffer(NULL), m_count(0), m_build(build), m_diskless(false){
			
		}
		SpellSearch::Collector::~Collector()
		{
			BondChangeBuffer* buffer = (BondChangeBuffer*)m_buffer;
			if (buffer)
			{
				delete buffer;
			}
			if (m_build)
				GetSearchEngine()->BuildIndex(m_diskless);
		}
		void SpellSearch::Collector::AddChange(int id, int type, const char* oldName, int oldlen, const char* name, int len)
		{
			if (strcmp(oldName, name) == 0)
				return;
			m_count++;
			((BondChangeBuffer*)GetBuffer())->AddChange(id, (kChangeType)type, oldName,oldlen, name,len);
		}
		void SpellSearch::Collector::AddNameChange(int id, const char* oldName, int oldlen, const char* name, int len)
		{
			if (strcmp(oldName, name) == 0)
				return;
			m_count++;
			((BondChangeBuffer*)GetBuffer())->AddNameChange(id, oldName,oldlen, name,len);
		}
		void SpellSearch::Collector::AddNameEnChange(int id, const char* oldName, int oldlen, const char* name, int len)
		{
			if (strcmp(oldName, name) == 0)
				return;
			m_count++;
			((BondChangeBuffer*)GetBuffer())->AddNameEnChange(id, oldName, oldlen, name, len);
		}
		void SpellSearch::Collector::AddCodeChange(int id, const char* oldCode, int oldlen, const char* code, int len)
		{
			if (strcmp(oldCode, code) == 0)
				return;
			m_count++;
			((BondChangeBuffer*)GetBuffer())->AddCodeChange(id, oldCode,oldlen, code,len);
		}

		void SpellSearch::Collector::Commit()
		{
			if (m_buffer != NULL)
			{
				BondChangeBuffer* buffer = (BondChangeBuffer*)m_buffer;
				GetSearchEngine()->AddBondChange(buffer);
				buffer->Reset();
			}
			m_count = 0;
		}
		void* SpellSearch::Collector::GetBuffer()
		{
			if (m_buffer == NULL)
				m_buffer = new BondChangeBuffer();
			return m_buffer;
		}
		void SpellSearch::SelectEngine(kEngineType type)
		{
			gs_use_refactor = type == kEngineTypeRefactor;
		}

		void SpellSearch::GetPinyinBuffer(const wchar_t* buffer, int len, wchar_t* quanbuf, int& quanlen, wchar_t* jianbuf, int& jianlen)
		{
			Spell::Parse(buffer, len, quanbuf, quanlen, jianbuf, jianlen);
		}

        void SpellSearch::GetAllKeys(std::vector<std::wstring>& keys)
		{
			GetSearchEngine()->GetAllKeys(keys);
		}
        void SpellSearch::FindBonds(const std::wstring& text, Listener* listener)
		{
			GetSearchEngine()->FindBonds(text, listener);
		}
		void SpellSearch::FindBonds(unsigned short const * text, int len, Listener* listener)
		{
			if (text && len>=0)
                GetSearchEngine()->FindBonds(std::wstring((const wchar_t*)text,len), listener);
		}
	}
}
